#ifndef __OPENGL_TEXTURE_HH__
#define __OPENGL_TEXTURE_HH__

#include <glad/glad.h>
#include <string>
#include <vector>

namespace opengl
{
class Texture
{
private:
    //! @brief 构造函数
    Texture(unsigned int index, unsigned int id, unsigned int type = 0x0DE1);

public:
    //! @brief 析构函数
    ~Texture() noexcept = default;

    //! @brief 绑定 texObject
    void bind()
    {
        glBindTexture(this->_texType, this->_texObject);
    }

    //! @brief 激活 _texIndex 纹理
    void active()
    {
        glActiveTexture(GL_TEXTURE0 + this->_texIndex);
        glBindTexture(this->_texType, this->_texObject);
    }

    //! @brief 解绑
    void unbind()
    {
        glBindTexture(this->_texType, 0);
    }

    //! @brief 释放纹理对象
    void free()
    {
        glDeleteTextures(1, &(this->_texObject));
    }

private:
    static std::string textureFolderPath;
    //! @brief 返回纹理完整路径
    static std::string completeTexturePath(const std::string& textureName)
    { return Texture::textureFolderPath + textureName; }

    //! @brief 静态函数，加载纹理
    static unsigned int create2DTexture(const std::string &textureName, bool reverse = true,
                                    unsigned int sAroundWay = 0x2901,
                                    unsigned int tAroundWay = 0x2901,
                                    unsigned int minFilterWay = 0x2601, 
                                    unsigned int maxFilterWay = 0x2601);

    //! @brief 静态函数，加载立方体贴图
    static unsigned int createCubemapTexture(const std::vector<std::string>& faces, bool reverse = true);

public:
    //! @brief 获取 2D 纹理 对象
    static Texture* load2DTexture(const std::string &textureName, bool reverse = true,
                                    unsigned int sAroundWay = 0x2901,
                                    unsigned int tAroundWay = 0x2901,
                                    unsigned int minFilterWay = 0x2601, 
                                    unsigned int maxFilterWay = 0x2601);

    //! @brief 获取 立方体纹理 对象
    static Texture* loadCubemapTexture(const std::vector<std::string>& faces, bool reverse = true);
    
    //! @brief 获取纹理
    static Texture* getTexture(const std::string &filename);

private:
     //! @brief 纹理对象在整个系统坐标，TEXURE0、TEXURE1..
    unsigned int _texIndex;
    //! @brief 纹理对象，glGen 函数返回的值
    unsigned int _texObject;
    //! @brief 纹理类型
    unsigned int _texType;

public:
    //! @brief 纹理属性
    unsigned int index() const
    { return this->_texIndex; }

    unsigned int id() const
    { return this->_texObject; }

    unsigned int* idptr()
    {
        return &this->_texObject;
    }

    void setIndex(unsigned int index) 
    { this->_texIndex = index; }
};
}

#endif